<?php

namespace App\Console\Commands\Plane;

use App\Models\Common\Area\Repositories\Interfaces\AreaRepositoryInterface;
use App\Models\Plane\Airports\Repositories\Interfaces\AirportRepositoryInterface;
use App\Models\Plane\Cities\Repositories\Interfaces\PlaneCityRepositoryInterface;
use App\Trip\Geo\Amap\POI;
use App\Trip\Plane\Providers\Ctrip\Query\Cities;
use Exception;
use GuzzleHttp\Exception\GuzzleException;
use Illuminate\Console\Command;
use Laravel\Octane\Exceptions\DdException;
use Maatwebsite\Excel\Facades\Excel;

class AirportsCrawl extends Command
{
    /**
     * The name and signature of the console command.
     *
     * @var string
     */
    protected $signature = 'airports:crawl {type} {--city_name=}';

    /**
     * The console command description.
     *
     * @var string
     */
    protected                      $description = '采集机场';
    private string|array|bool|null $type;

    /**
     * Execute the console command.
     *
     * @return int
     */
    public function handle()
    {
        $this->poi  = new POI();
        $this->type = $this->argument('type');
        $city_name  = $this->option('city_name');
        if ($city_name) {
            $this->crawlByCityName($city_name);
        } else {

            $airports = Excel::toArray(collect(), storage_path('plane/seeds/plane_airports.xlsx'));
            $aps      = $airports[0];
            unset($aps[0]);
            $plane_cities = file_get_contents(storage_path('plane/city.json'));
            $cities       = json_decode(json_decode($plane_cities, true), true);
            $cs           = collect($cities['cities'])->values()->flatten(1)
                                                      ->where('countryName', "中国")
                                                      ->toArray();

            foreach ($cs as $c) {
                try {
                    $this->crawlByCityName($c['cityName']);
                } catch (GuzzleException $e) {
                }
            }
        }
    }

    /**
     * @throws DdException
     * @throws GuzzleException
     */
    private function crawlByCityName(string $city_name, array $data = [])
    {
        $cityRepo    = app(PlaneCityRepositoryInterface::class);
        $areaRepo    = app(AreaRepositoryInterface::class);
        $airportRepo = app(AirportRepositoryInterface::class);
        if ($this->type == 'ctrip') {
            $cities = new Cities();
            $res    = $cities->airports($city_name);
            foreach ($res as $re) {
                $names   = $re["names"];
                $isChina = in_array("中国", $names);
                $type    = $re['poiType'];
                if ($type == 'CITY') {
                    if ($isChina) {
                        $cd = [
                            'name' => $re['cityName'],
                            'code' => $re['cityCode'],
                        ];
                        $c  = $areaRepo->findByName($re['cityName']) ?: $areaRepo->fuzzyFind($re['cityName'], 'city');
                        if ($c) {
                            $cd['adcode'] = $c->getAdCode();
                        }
//                        $cityRepo->addCity($cd);
                    } else {
                        $this->error("{$city_name} not china ".json_encode($names, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES));
//                        $cityRepo->delByCode($re['cityCode']);
                    }

                    $airports = $re['airports'];
                    foreach ($airports as $air) {
                        if ($isChina) {

                            $a = $airportRepo->findOneByCode($air['airportCode']);
                            if ($a?->getProvinceCode()) {
                                continue;
                            }
                            $base_data = [
                                'name'          => $air['airportName'],
                                'short_name'    => $data[6] ?? '',
                                'name_uy'       => $data[2] ?? '',
                                'short_name_uy' => $data[7] ?? '',
                                'code'          => $air['airportCode'],
                                'city_code'     => $air['cityCode'],
                            ];
                            $positions = $this->poi->searchByKeywords(
                                $air['airportName'],
                                150104,
                                '',
                                5
                            );
                            $p_data    = [];
                            foreach ($positions as $position) {
                                $p_data = [
                                    'pcode'          => $position['pcode'],
                                    'citycode'       => $position['citycode'],
                                    'adcode'         => $position['adcode'],
                                    'pname'          => $position['pname'],
                                    'cityname'       => $position['cityname'],
                                    'adname'         => $position['adname'],
                                    'location'       => $position['location'],
                                    'enter_location' => json_encode($position['entr_location'], 256 | 64),
                                    'tel'            => json_encode($position['tel'], 256 | 64),
                                    'poi_id'         => $position['id'],
                                    'navi_id'        => json_encode($position['navi_poiid'], 256 | 64),
                                    'address'        => json_encode($position['address'], 256 | 64),
                                    'state'          => 0,// 正常
                                    'amap_name'      => $position['name'],
                                    'match_type'     => 150104,
                                    'match_state'    => 1,
                                ];
//                                if (\Str::contains($base_data['name'], $p_data['amap_name'])) {
                                break;
//                                }
                            }

                            $base_data = array_merge($base_data, $p_data);
                            $airportRepo->addAirport($base_data);
                        } else {
                            try {
                                $this->error("{$city_name} not china ".json_encode($names, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES));
                                $airportRepo->delByCode($re['airportCode']);
                            } catch (Exception $e) {
                                $this->error(json_encode($re, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES));
                            }
                        }
                    }
                }

                if ($type == 'AIRPORT') {
                    if ($isChina) {
                        $a = $airportRepo->findOneByCode($re['airportCode']);
                        if ($a?->getProvinceCode()) {
                            continue;
                        }
                        $base_data = [
                            'name'          => $re['airportName'],
                            'code'          => $re['airportCode'],
                            'short_name'    => $data[6] ?? '',
                            'name_uy'       => $data[2] ?? '',
                            'short_name_uy' => $data[7] ?? '',
                            'city_code'     => $re['cityCode'],
                        ];

                        $positions = $this->poi->searchByKeywords(
                            $re['airportName'],
                            150104,
                            '',
                            5
                        );
                        $p_data    = [];
                        foreach ($positions as $position) {
                            $p_data = [
                                'pcode'          => $position['pcode'],
                                'citycode'       => $position['citycode'],
                                'adcode'         => $position['adcode'],
                                'pname'          => $position['pname'],
                                'cityname'       => $position['cityname'],
                                'adname'         => $position['adname'],
                                'location'       => $position['location'],
                                'enter_location' => json_encode($position['entr_location'], 256 | 64),
                                'tel'            => json_encode($position['tel'], 256 | 64),
                                'poi_id'         => $position['id'],
                                'navi_id'        => json_encode($position['navi_poiid'], 256 | 64),
                                'address'        => json_encode($position['address'], 256 | 64),
                                'state'          => 0,// 正常
                                'amap_name'      => $position['name'],
                                'match_type'     => 150104,
                                'match_state'    => 1,
                            ];
//                            if (\Str::contains($base_data['name'], $p_data['amap_name'])) {
                            break;
//                            }
                        }

                        $base_data = array_merge($base_data, $p_data);
                        $this->info(json_encode($base_data, 64 | 256));
                        $airportRepo->addAirport($base_data);
                    } else {
                        $airportRepo->delByCode($re['airportCode']);
                    }
                }
            }
        } elseif ($this->type == 'qunar') {
            $qunar_cities = new \App\Trip\Plane\Providers\Qunar\Query\Cities();
            $res          = $qunar_cities->airports($city_name);
            foreach ($res as $re) {
                $isChina = true;
                if (isset($re['suggestSearch']) && is_array($re['suggestSearch'])) {
                    $countryName = $re['suggestSearch']['countryName'];
                    if ($countryName != '中国') {
                        $isChina = false;
                    }
                }

                if (isset($re['canSearch']) && is_array($re['canSearch'])) {
                    $countryName = $re['canSearch']['countryName'];
                    if ($countryName != '中国') {
                        $isChina = false;
                    }
                }


                if ($re['typeName'] == '城市') {
                    if ($isChina) {
                        if ($re['code']) {
                            continue;
                        }
                        $cd = [
                            'name' => $re['cityName'],
                            'code' => $re['code'],
                        ];
                        $c  = $areaRepo->findByName($re['cityName']) ?: $areaRepo->fuzzyFind($re['cityName'], 'city');
                        if ($c) {
                            $cd['adcode'] = $c->getAdCode();
                        }
//                        $cityRepo->addCity($cd);
                    } else {
                        $this->error("{$city_name} not china ".json_encode($re, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES));
//                        $cityRepo->delByCode($re['code']);
                    }
                    continue;
                }


                try {
                    if ($re['typeName'] == '包含') {
                        if (isset($re['airportName'])) {
                            $airport = $airportRepo->findOneByCode($re['code']);
                            if (!$isChina) {
                                if ($airport) {
                                    $airportRepo->delByCode($re['code']);
                                }
                                continue;
                            }
                            if (!$airport) {
                                $this->warn($re['airportName']."-".$re["code"]."不存在怎么办");
                            } else {
                                $airportRepo->updateAirport($airport, [
                                    'short_name' => $re['airportName'],
                                ]);
                            }
                            $this->info("包含:{$city_name} ".$re['airportName']."-".$re["code"]);
                        } else {
                            $this->error(json_encode($re, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES));
                        }
                    }

                    if ($re['typeName'] == '机场') {
                        $airport  = $airportRepo->findOneByCode($re['code']);
                        $cityname = $re['cityName'];

                        if (!$isChina) {
                            if ($airport) {
                                $airportRepo->delByCode($re['code']);

                            }
                            continue;
                        }

                        if (!$airport) {
                            $city      = $cityRepo->findOneByName($cityname);
                            $base_data = [
                                'name'       => $re['airportName'],
                                'code'       => $re['code'],
                                'city_code'  => $city?->code ?: $re['code'],
                                'short_name' => $re['airportName'],
                            ];
                            $positions = $this->poi->searchByKeywords(
                                $re['airportName'],
                                150104,
                                '',
                                5
                            );
                            $p_data    = [];
                            foreach ($positions as $position) {
                                $p_data = [
                                    'pcode'          => $position['pcode'],
                                    'citycode'       => $position['citycode'],
                                    'adcode'         => $position['adcode'],
                                    'pname'          => $position['pname'],
                                    'cityname'       => $position['cityname'],
                                    'adname'         => $position['adname'],
                                    'location'       => $position['location'],
                                    'enter_location' => json_encode($position['entr_location'], 256 | 64),
                                    'tel'            => json_encode($position['tel'], 256 | 64),
                                    'poi_id'         => $position['id'],
                                    'navi_id'        => json_encode($position['navi_poiid'], 256 | 64),
                                    'address'        => json_encode($position['address'], 256 | 64),
                                    'state'          => 0,// 正常
                                    'amap_name'      => $position['name'],
                                    'match_type'     => 150104,
                                    'match_state'    => 1,
                                ];
//                                if (\Str::contains($base_data['name'], $p_data['amap_name'])) {
                                break;
//                                }
                            }

                            $base_data = array_merge($base_data, $p_data);
                            $airportRepo
                                ->addAirport($base_data);
                            $this->warn($re['airportName']."-".$re["code"]."不存在怎么办");
                        } else {
                            $airportRepo->updateAirport($airport, [
                                'short_name' => $re['airportName'],
                            ]);
                        }
                        $this->info("机场:{$city_name} ".$re['airportName']."-".$re["code"]);
                    }
                } catch (Exception $e) {
                    var_dump($re);
                }
            }
        }
//		$this->info(json_encode($res, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES));
    }
}
